const fs = require("fs");
const path = require("path");

// 读取用户认证配置
function fn读取用户认证配置() {
  console.log("开始读取用户认证配置文件");
  try {
    const _配置路径 = path.join(__dirname, "../", "配置", "用户认证.json");
    console.log(`📂 尝试读取用户认证配置文件: ${_配置路径}`);
    const _文件内容 = fs.readFileSync(_配置路径, "utf8");
    console.log("📄 用户认证文件读取成功");
    const _用户列表 = JSON.parse(_文件内容);
    console.log(`_用户列表`, _用户列表);
    return _用户列表;
  } catch (error) {
    console.error("❌ 读取用户认证配置失败:", error.message);
    console.error("💥 由于用户认证配置读取失败，程序即将退出");
    process.exit(1); // 直接结束程序
  }
}

// 读取用户认证配置
const _用户列表 = fn读取用户认证配置();

// 确保日志文件存在，不存在则创建
const _日志路径 = path.join(__dirname, "../", "配置", "认证失败记录.log");
function fn确保日志文件存在() {
  try {
    // 检查文件是否存在
    fs.accessSync(_日志路径, fs.constants.F_OK);
  } catch (error) {
    // 文件不存在，创建空文件
    fs.writeFileSync(_日志路径, "", "utf8");
    console.log(`📝 创建认证失败记录文件: ${_日志路径}`);
  }
}
fn确保日志文件存在();

// 写入认证失败记录
function fn写入认证失败记录(访问IP, 请求URL) {
  try {
        // 转换为北京时间，不受设备时区影响
    const _现在时间 = new Date();
    const _北京时间 = new Date(_现在时间.getTime() + 8 * 60 * 60 * 1000);
    const _当前时间 = _北京时间.toISOString().replace('T', ' ').substring(0, 19);
    
    const _日志内容 = `[${_当前时间}] IP ${访问IP}  URL ${请求URL}\n`;

    // 追加写入日志文件
    fs.appendFileSync(_日志路径, _日志内容, "utf8");
    console.log(`📝 认证失败记录已保存`);
  } catch (error) {
    console.error("❌ 写入认证失败记录时出错:", error.message);
  }
}

// 用户认证中间件
function fn用户认证中间件(req, res, next) {
  // 获取请求中的token参数
  const _令牌 = req.query.token || req.query.Token || req.query.TOKEN;

  const _客户端IP = req.ip || req.connection.remoteAddress || "未知IP";

  // 如果没有token参数，拦截请求
  if (!_令牌) {
    console.log(`🚫 当前请求 ${req.method} ${req.url} 失败，缺少认证参数`);
    fn写入认证失败记录(_客户端IP, req.url);
    return res.status(401).send("缺少认证参数");
  }

  // 如果配置读取失败或为空，拦截请求
  if (!_用户列表 || _用户列表.length === 0) {
    console.log(
      `🚫 当前请求 ${req.method} ${req.url} 失败，用户认证配置读取失败`
    );
    return res.status(500).send("服务器配置错误");
  }

  // 查找匹配的用户
  const _匹配用户 = _用户列表.find((用户) => 用户.令牌 === _令牌);

  // 如果找到匹配的用户
  if (_匹配用户) {
    console.log();
    console.log(`✅ 当前访问用户: ${_匹配用户.用户名}`);
    console.log(`请求地址: ${req.method} ${req.url.split("?")[0]}`);
    req.当前用户 = _匹配用户; // 将用户信息附加到请求对象上
    next(); // 继续执行下一步
  } else {
    // 如果没有找到匹配的用户，拦截请求
    console.log(`🚫 当前请求 ${req.method} ${req.url} 验证失败，令牌不匹配`);
    fn写入认证失败记录(_客户端IP, req.url);
    return res.status(401).send("认证失败，令牌不匹配");
  }
}

module.exports = fn用户认证中间件;
